package com.lb.tools.lbtools.tools.file;

import org.apache.commons.io.IOUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.CTAltChunk;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author 刘宾
 * @version V1.0
 * @Description 文件合并工具类
 * @date 2018/9/3 14:15
 * @since V1.0
 */
public class FileMargeUtils {

        public static InputStream mergeDocx(final List<InputStream> streams) throws Docx4JException, IOException {

            WordprocessingMLPackage target = null;
            final File generated = File.createTempFile("generated", ".docx");

            int chunkId = 0;
            Iterator<InputStream> it = streams.iterator();
            while (it.hasNext()) {
                InputStream is = it.next();
                if (is != null) {
                    if (target == null) {
                        // Copy first (master) document
                        OutputStream os = new FileOutputStream(generated);
                        os.write(IOUtils.toByteArray(is));
                        os.close();

                        target = WordprocessingMLPackage.load(generated);
                    } else {
                        // Attach the others (Alternative input parts)
                        insertDocx(target.getMainDocumentPart(), IOUtils.toByteArray(is), chunkId++);
                    }
                }
            }

            if (target != null) {
                target.save(generated);
                return new FileInputStream(generated);
            } else {
                return null;
            }
        }

    /**
     * 插入文档
     * @param main
     * @param bytes
     * @param chunkId
     */
        private static void insertDocx(MainDocumentPart main, byte[] bytes, int chunkId) {
            try {
                AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(
                        new PartName("/part" + chunkId + ".docx"));
                // afiPart.setContentType(new ContentType(CONTENT_TYPE));
                afiPart.setBinaryData(bytes);
                Relationship altChunkRel = main.addTargetPart(afiPart);

                CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
                chunk.setId(altChunkRel.getId());

                main.addObject(chunk);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /**
         * @Description 文档合并入口方法
         * @author (huangzhongwei)
         * @version V1.0
         * @since V1.0
         * @date 2018/9/3 14:11
         *
         */
        public static Boolean fileMerge(String startFile,String endFile,String finalFile) throws IOException, Docx4JException {
            List li = new ArrayList();
            {
                FileInputStream inout = new FileInputStream(new File(startFile));
                li.add(inout);
            }
            {
                FileInputStream inout = new FileInputStream(new File(endFile));
                li.add(inout);
            }
            FileOutputStream out = new FileOutputStream(finalFile);

            InputStream input = mergeDocx(li);

            byte[] buffer = new byte[256];

            int b = 0;

            while ((b = input.read(buffer)) != -1) {

                //4.写到输出流(out)中

                out.write(buffer, 0, b);

            }
            return true;
        }
		
		/*  依赖
			<dependency>
			<groupId>org.docx4j</groupId>
			<artifactId>docx4j</artifactId>
			<version>3.1.0</version>
		</dependency>

		*/
}
